vlwkaos' digital garden

JavaScript - Call, Apply, Bind

this

먼저 [[JavaScript - this]]를 알아보자.

Scope and Closure

  • Scope는 변수가 발견될 수 있는 범위를 뜻한다. 예를 들어 함수는 local scope를 가진다. 함수 내에서 선언된 변수는 함수 내에서만 참조가 가능하다.
  • Javascript는 함수가 반환을 했더라도 하위 함수에서 그 함수를 호출하는 상위 함수의 변수를 참조할 수 있다. 이 현상을 closure라고 한다.
  • Javascript 엔진은 변수가 사용될 때 현재 실행되는 context를 벗어나 바깥에서까지 찾으려 한다.

👀 더 자세한 내용은 [[JavaScript - Scope]], [[JavaScript - Closure]]를 참조한다.

Call, Apply, Bind

function foo() {
  return this // undefined in strict mode
}

위와 같은 함수를 strict mode에서 그냥 호출하면 this에 아무것도 set하지 않았으므로 undefined를 반환한다.

// 이어서...
const bar = {
    z: 1;
}

foo.call(bar); // bar 객체를 참조, 바로 실행 -> bar를 반환
foo.apply(bar); // bar 객체를 참조, 바로 실행 -> bar를 반환

const foobind = foo.bind(bar); // bar를 this로 참조하는 새로운 foo 함수 반환

call, 과 apply의 차이점은 함수 호출시 인자를 어떤 형태로 넘기느냐이다.

  • call은 함수에 인자를 전달하는 것 처럼 차례대로 인자를 넘길 수 있다.
    • func.call(this, 1,2,3,4)
  • apply는 배열로 인자를 한꺼번에 전달하여 호출.
    • func.apply(this, [1, 2, 3, 4, 5])
  • bind 는 원하는 this를 참조하는 새로운 함수를 반환
    • func.bind(this)

언제 사용하나?

Partially applied functions

부분 적용 함수를 만들 때 사용한다. 이게 무엇이냐. 어떤 함수의 인자 값 일부를 고정한 함수를 새로 만드는 것이다.

function addNumbers(a, b) {
  return a + b
}

const addTwo = addNumbers.bind(null, 2)

console.log(addTwo(3)) // 5

setTimeout() 호출시

정확히는 함수내에서 원하는 this를 정확히 참조하고 싶을 때 사용한다. setTimeout()와 같은 전역 함수는 이미thiswindow와 같은 전역 객체를 참조한다. 그렇기 때문에 클래스 안에서 호출하더라도 클래스 인스턴스가 this로 참조되지 않는다. 이럴 때 인스턴스를 bind한 함수를 만들어 전달하면 된다.

JavaScript - Call, Apply, Bind